package com.rtsapp.server.network.protocol.telnet;

import com.rtsapp.server.network.server.NettyServerChannelInitializer;
import com.rtsapp.server.network.session.netty.NettySessionManager;
import com.rtsapp.server.logger.Logger;

import com.rtsapp.server.module.Application;

import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;


public class TelnetServerInitializer extends NettyServerChannelInitializer {

	protected static final Logger logger =com.rtsapp.server.logger.LoggerFactory.getLogger( TelnetServerInitializer.class );

	private static final StringDecoder DECODER = new StringDecoder();
	private static final StringEncoder ENCODER = new StringEncoder();

	private final TelnetServerHandler serverHandler ;
	private final SslContext sslCtx;


	public TelnetServerInitializer( boolean ssl, TelnetServerHandler serverHandler ) {
		
		this.serverHandler = serverHandler;
		
		SslContext initSSLCtx = null;
		if (ssl) {
			try{
				SelfSignedCertificate ssc = new SelfSignedCertificate();
				initSSLCtx = SslContext.newServerContext( ssc.certificate(), ssc.privateKey() );
			}catch( Exception ex ){
				logger.error( "init SelfSignedCertificate error", ex );
				initSSLCtx = null;
			}
		} 

		sslCtx = initSSLCtx;
	}
	
	
	@Override
	public void initChannel(SocketChannel ch) throws Exception {

		ChannelPipeline pipeline = ch.pipeline();

		if (sslCtx != null) {
			pipeline.addLast(sslCtx.newHandler(ch.alloc()));
		}

		// Add the text line codec combination first,
		pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
		
		// the encoder and decoder are static as these are sharable
		pipeline.addLast(DECODER);
		pipeline.addLast(ENCODER);

		// and then business logic.
		pipeline.addLast(serverHandler);
	}


	@Override
	public boolean initialize(Application application, NettySessionManager sessionManager) {
		return serverHandler.initialize(application, sessionManager);
	}

}